[Spring]SpringMVC
MVC理论基础
WE中的三重架构:
- 每一层都有着各自的职责。
- 最关键的当属表示层,相当于直接与用户的浏览器打交道的一层,并且所有的请求都会进过它的解析,然后再告知业务层进行处理,任何页面的返回和数据填充也全靠表示层来完成,因此它实际上是整个三层架构中最关键的一层。
- 但需要编写大量的Servlet(也就是表示层实现)来处理来自浏览器的各种请求,但是我们发现,仅仅是几个很小的功能,以及几个很基本的页面,我们都要编写将近十个Servlet。
- 业务层负责数据处理。
- SpringMVC正是为了解决这种问题而生的,它是一个非常优秀的表示层框架,采用MVC思想设计实现。
MVC解释如下:
- M是指业务模型(Model):通俗的讲就是我们之前用于封装数据传递的实体类。
- V是指用户界面(View):一般指的是前端页面。
C则是控制器(Controller):控制器就相当于Servlet的基本功能,处理请求,返回响应。
SpringMVC正是希望这三者之间进行解耦,实现各干各的,更加精细地划分对应的职责。
- 最后再将View和Model进行渲染,得到最终的页面并返回给前端(就像之前使用Thymeleaf那样。
- 把实体数据对象和前端页面都给到Thymeleaf,然后它会将其进行整合渲染得到最终有数据的页面,而本教程也会使用Thymeleaf作为视图解析器进行讲解)
Controller控制器
- 它shyingDispatcherServlet替代Tomact为我们提供的默认静态资源Servlet。
- 现在所有的请求都会经过DispatcherServlet进行处理。
- DispatchServlet的作用:
- 我们的请求到达Tomcat服务器之后,会交给当前的Web应用程序进行处理。
- SpringMVC使用DispatcherServlet来处理所有请求,它被作为一个统一的访问点,所有的请求全部由它来进行调度。
- 当一个请求经过DispatcherServlet之后,会先走HandlerMapping,它会将请求映射为HandlerExecutionChain,依次经过HandlerInterceptor有点类似于之前我们所学的过滤器,不过在SpringMVC中我们使用的是拦截器。
- 然后再交给HandlerAdapter,根据请求的路径选择合适的控制器进行处理,控制器处理完成之后,会返回一个ModelAndView对象,包括数据模型和视图,通俗的讲就是页面中数据和页面本身(只包含视图名称即可)。
- 返回ModelAndView之后,会交给ViewResolver(视图解析器)进行处理,视图解析器会对整个视图页面进行解析。
- 解析完成后,就需要将页面中的数据全部渲染到View中,最后返回给DispatcherServlet一个包含所有数据的成形页面,再响应给浏览器,完成整个过程。
@RequestMapping
- 将请求和处理请求的方法建立一个映射关系,当收到请求时就可以根据映射关系调用对应的请求处理方法,
注解的定义如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public RequestMapping {
String name() default "";
String[] value() default {};
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}@AliasFor(“path”):别名
其中最关键的是path属性(等价于value),它决定了当前方法处理的请求路径,注意路径必须全局唯一,任何路径只能有一个方法进行处理,它是一个数组,也就是说此方法不仅仅可以只用于处理某一个请求路径,我们可以使用此方法处理多个请求路径。
现在我们访问/index或是/test都会经过此方法进行处理。
我们接着来看下一个method属性,顾名思义,它就是请求的方法类型,我们可以限定请求方式,比如:
1
2
3
4
public ModelAndView index(){
return new ModelAndView("index");
}
@RequestParam和@RequestHeader详解
- 我们可以通过这两种方法获取请求中的参数:
- 我们只需要为方法添加一个形式参数,并在形式参数前面添加@RequestParam注解即可:
1
2
3
4
5
public ModelAndView index({ String username)
System.out.println("接受到请求参数:"+username);
return new ModelAndView("index");
} - 我们需要在@RequestParam中填写参数名称,参数的值会自动传递给形式参数,我们可以直接在方法中使用。
- 注意,如果参数名称与形式参数名称相同,即使不添加@RequestParam也能获取到参数值。
- 一旦添加@RequestParam,那么此请求必须携带指定参数,我们也可以将require属性设定为false来将属性设定为非必须:
1
2
3
4
5
public ModelAndView index({ String username)
System.out.println("接受到请求参数:"+username);
return new ModelAndView("index");
} - 我们还可以直接设定一个默认值,当请求参数缺失时,可以直接使用默认值:
1
2
3
4
5
public ModelAndView index({ String username)
System.out.println("接受到请求参数:"+username);
return new ModelAndView("index");
} - 如果我们需要使用Servlet原本的一些类,比如:
1
2
3
4
5
public ModelAndView index(HttpServletRequest request){
System.out.println("接受到请求参数:"+request.getParameterMap().keySet());
return new ModelAndView("index");
} - 我们还可以直接将请求参数传递给一个实体类:
1
2
3
4
5
public class User {
String username;
String password;
} - 注意必须携带set方法或是构造方法中包含所有参数,请求参数会自动根据类中的字段名称进行匹配:
1
2
3
4
5
public ModelAndView index(User user){
System.out.println("获取到cookie值为:"+user);
return new ModelAndView("index");
}